'use strict';
import { EVENT } from '../constant';

class LeeEvent {

    constructor() {
        this[EVENT.CACHE] = [];
    }

    on(name, listen, context, times, weight = 0) {
        this[EVENT.CACHE].push({ name, listen, context, times, weight });
    }

    off(name, listen) {
        const cache = this[EVENT.CACHE];
        for (let i = 0; i < cache.length; i++) {
            if (cache[i].name !== name) continue;
            if (listen && cache[i].listen !== listen) continue;
            cache.splice(i--, 1);
        }
    }

    once(name, listen, context, weight = 0) {
        this[EVENT.CACHE].push({ name, listen, context, times: 1, weight });
    }

    emit(name, ...args) {
        const cache = this[EVENT.CACHE].filter(item => item.name === name).sort((cacheA, cacheB) => {
            return cacheB.weight - cacheA.weight;
        });
        for (const item of cache) {
            (item.context ? item.listen.bind(item.context) : item.listen)(...args);
            if (typeof item.times === 'number' && --item.times <= 0) this.off(name, item.listen);
        }
    }
}

LeeEvent.$globalEvent = new LeeEvent();
export default LeeEvent;
